<?php
/**
 * Responsible for perform the routing
 * Implements the design pattern protection proxy
 *
 * @version 3.0
 * @author Renan Henrique Abreu <renanhabreu@gmail.com>
 * @package Nucleo
 * @subpackage Nucleo.Controller
 * @copyright 2009-2010 Renan Abreu
 */
class Nucleo_Controller_Factory {
    /**
     * Current module identifier
     * @var String
     */
    static public $modulo;


    /**
     * Run controllers
     */
    static public function dispatch() {
        $request = self::getUrlRequest();
        //Modulo Da Aplicacao
        self::$modulo  =  $request['m'];
        //Controller Da Aplicacao
        $ctr     =  $request['c'];
        //Acao Da Aplicacao
        $act     =  $request['a'];

        //Identificador da Acao = Action
        $acao = $act.'Action';

        if(Nucleo_Load_Controller::findClass($ctr)) {

            //Realiza a autenticacao -- Padrao PROXY
            if(Nucleo_Controller_Authentication::isAllowed(self::$modulo,$ctr,$act)) {
                try {

                    $reflectionMethod = new ReflectionMethod($ctr,$acao);

                    $reflectionClass  = new ReflectionClass($ctr);
                    $controllerObject = $reflectionClass->newInstance();

                }catch (ReflectionException $e) {
                    echo Nucleo_Language_Translate::sifraMsg('008');
                    exit();
                }

                return $reflectionMethod->invoke($controllerObject);

            }else { //Usuario sem permissao de acesso
                throw new Nucleo_Exception_Authentication('012');
                exit();
            }

        }else {
            $dirModule = MODULE_PATH.self::$modulo;
            if(!is_dir($dirModule)) {
                throw new Nucleo_Exception_Gateway('023');
            }elseif(!is_dir($dirModule.'/Controller')) {
                throw new Nucleo_Exception_Gateway('013');
            }
            echo Nucleo_Language_Translate::sifraMsg('024');
            exit();
        }
    }

    /**
     * Redirect for an action if occur authentication exception
     * @param string module name
     * @param string controller name
     * @param string action name
     */
    static public function dispatchLogin($module,$controller,$action) {

        try {
            $return = self::dispatch();
        }catch (Nucleo_Exception_Authentication $e) {
            $url = Nucleo_Controller_Controller::url(Array('m'=>$module,'c'=>$controller,'a'=>$action));
            header("Location: ".$url);
            exit();
        }

        return $return;
    }

    /**
     * Translate url request
     * @return array
     */
    static private function getUrlRequest() {
        $url_base['URL']   = $_SERVER['REQUEST_URI'];
        $url_base['PARAM'] = $_SERVER['SCRIPT_NAME'];

        if(!MOD_REWRITE){
            $base = explode('?',$_SERVER['REQUEST_URI']);
            $diff = explode('/',$base[1]);
        }else{
            $url = explode('/',$url_base['URL']);
            $script = explode('/',$url_base['PARAM']);
            $diff = array_diff_assoc($url,$script);
        }
       
        $param = current($diff);
        $urlParameter['m'] = DEFAULT_MODULE; //module
        $urlParameter['c'] = DEFAULT_CONTROLLER; //controller
        $urlParameter['a'] = DEFAULT_ACTION; //action
        $arrayGet = NULL; //replace $_GET

        //search module,controller,action and $_GETs
        while($param) {

            if($param == 'm' || $param == 'c' || $param == 'a')
                $urlParameter[$param] = ucfirst(htmlentities(strtolower(next($diff))));
            else
                $arrayGet[$param] = htmlentities(next($diff));

            $param = next($diff);
        }


        if(isset($arrayGet)) {
            Nucleo_Registry_Registry::set('GET',$arrayGet);
            $_GET = NULL;

        }

        if(isset($_POST)) {
            Nucleo_Registry_Registry::set('POST',array_map('htmlentities',$_POST));
            $_POST = NULL;
        }

        return $urlParameter;
    }

    /**
     * Run controllers
     * @deprecated deprecated sice version 2.0.4
     */
    public function createController() {
        return self::dispatch();
    }
}
?>
